package com.zoe.onelink.auth.autoconfigure;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zoe.onelink.auth.client.AuthRemoteClient;
import com.zoe.onelink.auth.client.impl.AuthHttpClient;
import com.zoe.onelink.auth.client.impl.AuthNacosClient;
import com.zoe.onelink.auth.component.InnerUrlServices;
import com.zoe.onelink.auth.component.OneLinkBearerTokenExtractor;
import com.zoe.onelink.auth.component.OneLinkRedisTokenServices;
import com.zoe.onelink.auth.component.OneLinkRedisDifferentTokenServices;
import com.zoe.onelink.auth.component.OneLinkPermissionService;
import com.zoe.onelink.auth.component.ResourceAuthExceptionEntryPoint;
import com.zoe.onelink.auth.properties.AuthProperties;
import com.zoe.onelink.auth.registry.OnelinkKnife4jOauth2DocRegistry;
import com.zoe.onelink.auth.runner.RedisCompareRunner;
import com.zoe.onelink.redis.util.RedisUtil;
import com.zoe.onelink.upms.common.service.OneLinkTokenStore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurer;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.web.client.RestTemplate;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinHongKai
 * @date 2022-02-25 22:07
 */
@EnableConfigurationProperties(AuthProperties.class)
public class ResourceServerAutoConfiguration {

    @Bean("pms")
    public OneLinkPermissionService permissionService() {
        return new OneLinkPermissionService();
    }

    @Bean
    public OneLinkBearerTokenExtractor pigBearerTokenExtractor(AuthProperties authProperties) {
        return new OneLinkBearerTokenExtractor(authProperties);
    }

    @Bean
    public ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint(
            ObjectMapper objectMapper) {
        return new ResourceAuthExceptionEntryPoint(objectMapper);
    }

    @Bean
    public ResourceServerTokenServices oneLinkRedisTokenServices(OneLinkTokenStore oneLinkTokenStore) {
        return new OneLinkRedisTokenServices(oneLinkTokenStore);
    }


    @Bean
    @ConditionalOnClass({RestTemplate.class, DiscoveryClient.class})
    public AuthRemoteClient authNacosClient(RestTemplate restTemplate, OneLinkTokenStore oneLinkTokenStore){
        return new AuthNacosClient(restTemplate, oneLinkTokenStore);
    }


    @Bean
    @ConditionalOnProperty(prefix = "onelink.auth", name = "authUrl")
    @ConditionalOnMissingBean(AuthRemoteClient.class)
    public AuthRemoteClient authHttpClient(OneLinkTokenStore oneLinkTokenStore, AuthProperties authProperties){
        return new AuthHttpClient(oneLinkTokenStore, authProperties);
    }


    @Bean
    @Primary
    @ConditionalOnBean(AuthRemoteClient.class)
    @ConditionalOnMissingBean(AuthorizationServerConfigurer.class)
    public ResourceServerTokenServices oneLinkRedisDifferentTokenServices(
            AuthRemoteClient authRemoteClient, OneLinkTokenStore oneLinkTokenStore){
        return new OneLinkRedisDifferentTokenServices(authRemoteClient, oneLinkTokenStore);
    }


    @Bean
    @ConditionalOnBean(AuthRemoteClient.class)
    @ConditionalOnClass(RedisUtil.class)
    @ConditionalOnMissingBean(AuthorizationServerConfigurer.class)
    public RedisCompareRunner redisCompareRunner(){
        return new RedisCompareRunner();
    }


    @Bean
    public InnerUrlServices innerUrlServices(AuthProperties authProperties){
        return new InnerUrlServices(authProperties);
    }


    @Bean
    @ConditionalOnClass(Docket.class)
    public OnelinkKnife4jOauth2DocRegistry onelinkKnife4jOauth2DocRegistry() {
        return new OnelinkKnife4jOauth2DocRegistry();
    }
}
